/**
 * 
 */
package edu.arizona.bio5.onto.decomposition;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.semanticweb.owlapi.model.OWLEntity;

import uk.ac.manchester.cs.util.SetUtils;
import edu.arizona.bio5.onto.modularity.Signature;
import edu.arizona.bio5.onto.util.OntologyUtils;

/**
 * Label as a set of min seed signatures (not necessarily a complete set)
 * 
 * @author Pavel Klinov
 *
 */
public class MSSLabel implements Label, Iterable<Set<OWLEntity>> {

	public static final String TYPE = "MIN_SEED_SIGNATURES";
	
	private Collection<Set<OWLEntity>> m_seedSigs = null;
	private boolean m_complete = false;
	
	
	public MSSLabel(Collection<Set<OWLEntity>> seedSigs) {
		
		this(seedSigs, false);
	}
	
	public MSSLabel(Collection<Set<OWLEntity>> seedSigs, boolean complete) {
		
		m_complete = complete;
		m_seedSigs = seedSigs;
	}
	
	public Collection<Set<OWLEntity>> getSeedSignatures() {
		
		return m_seedSigs;
	}
	
	@Override
	public Iterator<Set<OWLEntity>> iterator() {
		return m_seedSigs.iterator();
	}
	
	public boolean isAtomRelevant(Set<OWLEntity> querySig) {		
		return SetUtils.containsSubset(m_seedSigs, querySig);
	}
	
	public boolean isAtomRelevant(Signature querySig) {
		//FIXME
		//This a very slow check at the moment
		//Solution: use something like Trie to store OWLEntities or just URIs
		for (Set<OWLEntity> sig : m_seedSigs) {
			if (containsAllURIs(sig, querySig)) {
				return true;
			}
		}
		
		return false;
	}

	private boolean containsAllURIs(Set<OWLEntity> sig, Signature querySig) {
		if (sig.size() > querySig.getURIs().size()) {
			return false;
		}
		else {
			//pretend there's no punning otherwise there could be two distinct entities with the same URI
			for (OWLEntity term : sig) {
				if (!querySig.getURIs().contains(term.getIRI().toURI())) {
					return false;
				}
			}			
			
			return true;
		}
	}

	public boolean isAtomIrrelevant(Set<OWLEntity> querySig) {
		//If we only store minimal seed signature, then this check is sound
		//since no subset of the query signature can be a minimal seed signature		
		return SetUtils.containsSuperset(m_seedSigs, querySig, true) || (m_complete && !isAtomRelevant(querySig));
	}
	
	public String toString() {
		
		Set<Set<String>> set = new HashSet<Set<String>>();
		
		for (Set<OWLEntity> sig : m_seedSigs) {
			
			Set<String> sigStr = new HashSet<String>();
			
			for (OWLEntity term : sig) sigStr.add(OntologyUtils.termToString(term));
			
			set.add(sigStr);
		}
		
		return set.toString();
	}
	
	public boolean isComplete() {
		
		return m_complete;
	}

	@Override
	public String getType() {
		return TYPE;
	}
}